gdk: Create a global shared GL context
authorMatthias Clasen <mclasen@redhat.com>
Tue, 4 Jun 2019 21:26:28 +0000 (21:26 +0000)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 4 Jun 2019 23:00:02 +0000 (23:00 +0000)
Create a global GL context that connects all
GL contexts on a display and lets us share textures
between them.

gdk/gdkinternals.h
gdk/gdksurface.c
gdk/wayland/gdkglcontext-wayland.c
gdk/x11/gdkglcontext-x11.c

index 143ed59529c5ea29f94ded43878593e13b853013..13b139f5ce4ad9b0d340fe3147d855d60343e208 100644 (file)
@@ -274,6 +274,8 @@ void gdk_surface_move_resize  (GdkSurface     *surface,
                                gint           width,
                                gint           height);
 
+GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
+
 G_END_DECLS
 
 #endif /* __GDK_INTERNALS_H__ */
index f6702914771c52d502900cdc9a5eea523889ed86..c1e57a591ca933b4b78bb345cd05ed60bad285b9 100644 (file)
@@ -1110,6 +1110,46 @@ gdk_surface_get_state (GdkSurface *surface)
   return surface->state;
 }
 
+GdkGLContext *
+gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
+{
+  static int in_shared_data_creation;
+  GdkDisplay *display;
+  GdkGLContext *context;
+
+  if (in_shared_data_creation)
+    return NULL;
+
+  in_shared_data_creation = 1;
+
+  display = gdk_surface_get_display (surface);
+  context = (GdkGLContext *)g_object_get_data (G_OBJECT (display), "gdk-gl-shared-data-context");
+  if (context == NULL)
+    {
+      GError *error = NULL;
+      context = GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface, FALSE, NULL, &error);
+      if (context == NULL)
+        {
+          g_warning ("Failed to create shared context: %s", error->message);
+          g_clear_error (&error);
+        }
+
+      gdk_gl_context_realize (context, &error);
+      if (context == NULL)
+        {
+          g_warning ("Failed to realize shared context: %s", error->message);
+          g_clear_error (&error);
+        }
+
+
+      g_object_set_data (G_OBJECT (display), "gdk-gl-shared-data-context", context);
+    }
+
+  in_shared_data_creation = 0;
+
+  return context;
+}
+
 GdkGLContext *
 gdk_surface_get_paint_gl_context (GdkSurface  *surface,
                                   GError    **error)
index 79751cb8fc96f5aa0e005bb7d67b942ac6c3b595..edeca4916c038b4e2bad5db4c99a65a6f81d5e9c 100644 (file)
@@ -47,6 +47,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
   GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
   GdkDisplay *display = gdk_gl_context_get_display (context);
   GdkGLContext *share = gdk_gl_context_get_shared_context (context);
+  GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface (context));
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
   EGLContext ctx;
   EGLint context_attribs[N_EGL_ATTRS];
@@ -114,7 +115,8 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
   ctx = eglCreateContext (display_wayland->egl_display,
                           context_wayland->egl_config,
                           share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
-                                        : EGL_NO_CONTEXT,
+                             : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
+                                                  : EGL_NO_CONTEXT,
                           context_attribs);
 
   /* If context creation failed without the legacy bit, let's try again with it */
@@ -136,7 +138,8 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
       ctx = eglCreateContext (display_wayland->egl_display,
                               context_wayland->egl_config,
                               share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
-                                            : EGL_NO_CONTEXT,
+                                 : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT (shared_data_context)->egl_context
+                                    : EGL_NO_CONTEXT,
                               context_attribs);
     }
 
index b95a18517cbcb6e39f123e1217725089996918e0..1385713609c0b582a773ab8a3139740349a5f4a9 100644 (file)
@@ -576,6 +576,7 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
   Display *dpy;
   DrawableInfo *info;
   GdkGLContext *share;
+  GdkGLContext *shared_data_context;
   GdkSurface *surface;
   gboolean debug_bit, compat_bit, legacy_bit, es_bit;
   int major, minor, flags;
@@ -586,6 +587,7 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
   context_x11 = GDK_X11_GL_CONTEXT (context);
   display_x11 = GDK_X11_DISPLAY (display);
   share = gdk_gl_context_get_shared_context (context);
+  shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
 
   gdk_gl_context_get_required_version (context, &major, &minor);
   debug_bit = gdk_gl_context_get_debug_enabled (context);
@@ -625,7 +627,7 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
   if (legacy_bit && !GDK_X11_DISPLAY (display)->has_glx_create_context)
     {
       GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating legacy GL context on request"));
-      context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share);
+      context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share ? share : shared_data_context);
     }
   else
     {
@@ -650,14 +652,14 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
       GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 context"));
       context_x11->glx_context = create_gl3_context (display,
                                                      context_x11->glx_config,
-                                                     share,
+                                                     share ? share : shared_data_context,
                                                      profile, flags, major, minor);
 
       /* Fall back to legacy in case the GL3 context creation failed */
       if (context_x11->glx_context == NULL)
         {
           GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating fallback legacy context"));
-          context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share);
+          context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share ? share : shared_data_context);
           legacy_bit = TRUE;
           es_bit = FALSE;
         }